﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using PPI.Client;
using PPI.Client.Logic.Distribution;
using PPI.Client.Utils;
using PPI.Entities.Distribution;
using PPI.Entities.Enumerator;
using PPI.Entities.Inspections;
using PPI.Entities.Lookup;
using PPI.Entities.XML;
using PPI.General;
using System.Linq;
using ENote=PPI.Entities.Distribution.ENote;

namespace PPI.CRUD
{
    public partial class frmDistributionEditor : frmBase
    {
        #region - Properties -

        public EDistributionPole Pole { get; set; }
        public EXmlOutboxBase m_OutboxBase {get; set;}
        private List<EDistributionPoleImage> imagesToRemove = new List<EDistributionPoleImage>();

        #endregion

        private frmDistributionMeterEditor m_DistributionMeterEditor;
        private frmDistributionTransformerEditor m_DistributionTransformerEditor;
        private frmDistributionSectionalizerEditor m_DistributionSectionalizerEditor;
        private frmDistributionRecloserEditor m_DistributionRecloserEditor;

        public frmDistributionEditor()
        {
            InitializeComponent();
        }

        private void LoadControls()
        {
            lstTopTypes.DataSource = LCacheDistributionDataSingleton.Instance.Tops;
            lstPhases.DataSource = LCacheDistributionDataSingleton.Instance.Phases;
            lstNotes.DataSource = LCacheDistributionDataSingleton.Instance.Notes;

            string selectOption = "Select an option ...";

            DropdownHelper.FillDropdown(ddlClass, LCacheDistributionDataSingleton.Instance.Classes.ToArray(), selectOption);
            DropdownHelper.FillDropdown(ddlLength, LCacheDistributionDataSingleton.Instance.Lengths.ToArray(), selectOption);
            DropdownHelper.FillDropdown(ddlMap, LCacheDistributionDataSingleton.Instance.Maps.ToArray(), selectOption);
            DropdownHelper.FillDropdown(ddlSpecie, LCacheDistributionDataSingleton.Instance.Species.ToArray(), selectOption);
            DropdownHelper.FillDropdown(ddlTreatment, LCacheDistributionDataSingleton.Instance.Treatments.ToArray(), selectOption);
            DropdownHelper.FillDropdown(ddlInspectionType, LCacheDistributionDataSingleton.Instance.Inspections.ToArray(), selectOption);
            DropdownHelper.FillDropdown(ddlResultType, LCacheDistributionDataSingleton.Instance.ResultsTypes.ToArray(), selectOption);

            var kvs = LCacheDistributionDataSingleton.Instance.DistributionLookUps.Where(x => x.Type == DistributionLookUpType.Kv).ToList();
            DropdownHelper.FillDropdown(ddlKv, kvs.ToArray(), selectOption);

            var conductorTypes = LCacheDistributionDataSingleton.Instance.DistributionLookUps.Where(x => x.Type == DistributionLookUpType.ConductorType).ToList();
            DropdownHelper.FillDropdown(ddlConductorType, conductorTypes.ToArray(), selectOption);

            var acsrs = LCacheDistributionDataSingleton.Instance.DistributionLookUps.Where(x => x.Type == DistributionLookUpType.ACSR).ToList();
            DropdownHelper.FillDropdown(ddlACSR, acsrs.ToArray(), selectOption);

            int startSectionId = LCacheDistributionDataSingleton.Instance.Maps[LCacheDistributionDataSingleton.Instance.Maps.Count - 1].Id;

            DataTable dtSections = FillSpecificDataTableHelper.FillDataTable(startSectionId, 1, 36, 1);
            DropdownHelper.FillDropDown(ddlSection, dtSections, "Name", "Id", "1 to 36");

            DataTable dtYears = FillSpecificDataTableHelper.FillDataTable(1944, DateTime.Now.Year, 1);
            DropdownHelper.FillDropDown(ddlYear, dtYears, "Name", "Id", "Select an option...");

            DataTable dtLVisita = FillSpecificDataTableHelper.FillDataTable(1944, DateTime.Now.Year, 1);
            DropdownHelper.FillDropDown(ddlLVisit, dtLVisita, "Name", "Id", "Select an option...");

            DataTable dtGuards = FillSpecificDataTableHelper.FillDataTable(1, 8, 1);
            DropdownHelper.FillDropDown(ddlGuardsQuantity, dtGuards, "Name", "Id", "Select an option...");

            grdDistributionMeters.ShowContextMenu = true;
            grdDistributionMeters.ShowAssociateOption = false;
            grdDistributionMeters.OutboxBase = m_OutboxBase;

            grdDistributionTransformers.ShowContextMenu = true;
            grdDistributionTransformers.ShowAssociateOption = false;
            grdDistributionTransformers.OutboxBase = m_OutboxBase;

            if (m_OutboxBase.DatabaseType == DatabaseTypes.DistributionGPS)
                tabResult.Visible = false;
        }

        private void LoadImages()
        {
            pbxSelectedImage.Image = null;

            lstImages.DataSource = null;
            lstImages.Items.Clear();

            lstImages.DataSource = Pole.Images;
            lstImages.DisplayMember = "Title";
        }

        private void LoadMeters()
        {
            grdDistributionMeters.LoadMeters(Pole.Meters);
        }

        private void LoadTransformers()
        {
            grdDistributionTransformers.LoadTransformers(Pole.Transformers);
        }

        private void LoadSectionlizers()
        {
            gridDistributionSectionalizers.LoadSectionalizers(Pole.Sectionalizers);
        }

        private void LoadReclosers()
        {
            gridDistributionReclosers.LoadReclosers(Pole.Reclosers);
        }

        private void frmDistributionEditor_Load(object sender, EventArgs e)
        {
            if (Pole != null) 
            {
                LoadControls();
                LoadDistributionPole();
                LoadImages();
                LoadMeters();
                LoadTransformers();
                LoadSectionlizers();
                LoadReclosers();
            }

            tabMain.SelectedTab = tabPole;
        }

        private void LoadDistributionPole()
        {
            ddlClass.SelectedItem = Pole.Class;
            ddlLength.SelectedItem = Pole.Length;
            ddlMap.SelectedItem = Pole.Map;
            ddlSpecie.SelectedItem = Pole.Specie;
            ddlTreatment.SelectedItem = Pole.Treatment;
            ddlInspectionType.SelectedItem = Pole.InspectionResult.InspectionType;
            ddlResultType.SelectedItem = Pole.InspectionResult.Resultype;
            ddlKv.SelectedItem = Pole.Kv;
            ddlConductorType.SelectedItem = Pole.ConductorType;
            ddlACSR.SelectedItem = Pole.ACSR;

            if (Pole.Year != Int32.MinValue)
                ddlYear.SelectedIndex = DropdownHelper.GetItemIndex(ddlYear, Pole.Year.ToString());

            if (Pole.LVisit != DateTime.MinValue)
                ddlLVisit.SelectedIndex = DropdownHelper.GetItemIndex(ddlLVisit, Pole.LVisit.Year.ToString());

            if (Pole.Section.Id != Int32.MinValue)
                ddlSection.SelectedIndex = DropdownHelper.GetItemIndex(ddlSection, Pole.Section.Id.ToString());

            if (Pole.GuardsQuantity != Int32.MinValue)
                ddlGuardsQuantity.SelectedIndex = DropdownHelper.GetItemIndex(ddlGuardsQuantity, Pole.GuardsQuantity.ToString());

            txtInspBy.Text = Pole.InspBy;
            txtNumber.Text = Pole.Number;
            txtCircuit.Text = Pole.Circuit;
            txtComments.Text = Pole.InspectionResult.Comments;
            txtD804.Text = Pole.D804;
            chkIsElectrical.Checked = Pole.InspectionResult.IsElectrical;
            chkPoleTag.Checked = Pole.PoleTag;
            chkGroundWireRepair.Checked = Pole.GroundWireRepair;
            chkBillable.Checked = Pole.Billable;
            
            lstTopTypes.ClearSelected();
            foreach (EXMissionStructures_PoleTopType top in Pole.Tops)
            {
                //top.Key = top.Id.ToString();
                lstTopTypes.SetSelected(lstTopTypes.Items.IndexOf(top), true);
            }

            lstPhases.ClearSelected();
            foreach (EPhase phase in Pole.Phases)
                lstPhases.SetSelected(lstPhases.Items.IndexOf(phase), true);

            lstNotes.ClearSelected();
            foreach (ENote note in Pole.Notes)
                for (int i = 0; i < lstNotes.Items.Count; i++)
                    if (((ENote)lstNotes.Items[i]).Id.ToString().Equals(note.Key))
                        lstNotes.SetSelected(i, true);

            position1.SetLatitude(Pole.Latitude);
            position1.SetLongitude(Pole.Longitude);
        }

        private void lstImages_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                if (e.KeyCode == Keys.Delete)
                {
                    if (lstImages.SelectedIndex > -1)
                    {
                        EDistributionPoleImage tmpImage = (EDistributionPoleImage)lstImages.SelectedItem;

                        imagesToRemove.Add(tmpImage);
                        ((List<EDistributionPoleImage>)lstImages.DataSource).Remove(tmpImage);
                        LoadImages();
                    }
                }
            }
            catch (Exception ex)
            {
                RegisterError.SaveError(ex);
            }
        }

        private void lstImages_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (lstImages.SelectedIndex > -1)
                {
                    EDistributionPoleImage tmpImage = (EDistributionPoleImage)lstImages.SelectedItem;
                    viewImage(tmpImage);
                }
            }
            catch (Exception ex)
            {
                RegisterError.SaveError(ex);
            }
        }

        private void viewImage(EDistributionPoleImage image)
        {
            FileInfo poleImage = null;

            if (!Pole.isProjectPole)
            {
                if (image.Id == Int32.MinValue)
                    poleImage = new FileInfo(image.FullName);
                else
                    poleImage = new FileInfo(DirHelper.GetImagesDirectory(m_OutboxBase.ConnectionString) + Path.DirectorySeparatorChar + image.FileName);
            }
            else
            {
                poleImage = new FileInfo(image.GetTemporaryFolder());
            }


            if (poleImage != null)
            {
                if (poleImage.Exists)
                {
                    using (Stream s = File.OpenRead(poleImage.FullName))
                        pbxSelectedImage.Image = Image.FromStream(s);
                }
                else
                    pbxSelectedImage.Image = null;
            }
        }

        private void grdDistributionMeters_ClickedDelete(object sender, Controls.Grid.GridBaseEventArgs e)
        {
            try
            {
                if (grdDistributionMeters.CurrentMeters != null)
                {
                    EMeter selectedMeter = grdDistributionMeters.CurrentMeters.Find(delegate(EMeter meter) { return meter.Id == e.SelectedId; });
                    string _Message = "Distribution Meter id: " + selectedMeter.Id + " will be deleted from database. Are you sure you want to delete this inspection?";

                    if (MessageBox.Show(_Message, "Delete ", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
                    {
                        //Deletes from server.
                        if (Pole.isProjectPole)
                            LMeter.Delete(selectedMeter);

                        //Delete on local mobile database.
                        LMeter.Delete(grdDistributionMeters.OutboxBase.ConnectionString, selectedMeter);

                        MessageBox.Show("Deleted Succesfull");
                        grdDistributionMeters.Datagrid.Rows.Remove(e.SelectedRow);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                RegisterError.SaveError(ex);
            }
        }

        private void grdDistributionMeters_ClickedEdit(object sender, Controls.Grid.GridBaseEventArgs e)
        {
            if (m_DistributionMeterEditor == null)
                m_DistributionMeterEditor = new frmDistributionMeterEditor();

            m_DistributionMeterEditor.Meter = grdDistributionMeters.CurrentMeters.Find(delegate(EMeter meter) { return meter.Id == e.SelectedId; });
            m_DistributionMeterEditor.Pole = Pole;
            m_DistributionMeterEditor.m_OutboxBase = m_OutboxBase;

            m_DistributionMeterEditor.ShowDialog();
            LoadMeters();
        }
        
        private void grdDistributionTransformers_ClickedDelete(object sender, PPI.Controls.Grid.GridBaseEventArgs e)
        {
            try
            {
                if (grdDistributionTransformers.CurrentTransformers != null)
                {
                    ETransformer selectedTransformer = grdDistributionTransformers.CurrentTransformers.Find(delegate(ETransformer transformer) { return transformer.Id == e.SelectedId; });
                    string _Message = "Distribution Transformer id: " + selectedTransformer.Id + " will be deleted from database. Are you sure you want to delete this inspection?";

                    if (MessageBox.Show(_Message, "Delete ", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
                    {
                        //Delete on local mobile database.
                        LTransformer.Delete(m_OutboxBase.ConnectionString, selectedTransformer);

                        MessageBox.Show("Deleted Succesfull");
                        grdDistributionTransformers.Datagrid.Rows.Remove(e.SelectedRow);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                RegisterError.SaveError(ex);
            }
        }

        private void grdDistributionTransformers_ClickedEdit(object sender, PPI.Controls.Grid.GridBaseEventArgs e)
        {
            if (m_DistributionTransformerEditor == null)
                m_DistributionTransformerEditor = new frmDistributionTransformerEditor();

            m_DistributionTransformerEditor.Transformer = grdDistributionTransformers.CurrentTransformers.Find(delegate(ETransformer transformer) { return transformer.Id == e.SelectedId; });
            m_DistributionTransformerEditor.Pole = Pole;
            m_DistributionTransformerEditor.m_OutboxBase = m_OutboxBase;

            m_DistributionTransformerEditor.ShowDialog();
            LoadTransformers();
        }

        private EDistributionPole GetActualPole()
        {
            EDistributionPole actualPole = new EDistributionPole();

            actualPole.Id = Pole.Id;
            actualPole.AcquisitionDate = Pole.AcquisitionDate;
            actualPole.DistributionType = Pole.DistributionType;
            actualPole.ServerID = Pole.ServerID;
            actualPole.Inspector = Pole.Inspector;
            actualPole.Vendor = Pole.Vendor;
            actualPole.Project = Pole.Project;
            actualPole.Kv = Pole.Kv;
            actualPole.Class = ddlClass.SelectedItem as EXMissionStructures_PoleClass;
            actualPole.Length = ddlLength.SelectedItem as EXMissionStructures_PoleLength;
            actualPole.Map = ddlMap.SelectedItem as EMap;
            actualPole.Specie = ddlSpecie.SelectedItem as EXMissionStructures_PoleSpecies;
            actualPole.Treatment = ddlTreatment.SelectedItem as EXMissionStructures_PoleTreatment;
            actualPole.InspectionResult.InspectionType = ddlInspectionType.SelectedItem as EInspectionTypes;
            actualPole.InspectionResult.Resultype = ddlResultType.SelectedItem as EResultType;
            actualPole.Kv = ddlKv.SelectedItem as EDistributionLookUp;
            actualPole.ConductorType = ddlConductorType.SelectedItem as EDistributionLookUp;
            actualPole.ACSR = ddlACSR.SelectedItem as EDistributionLookUp;

            if (ddlYear.SelectedIndex > 0)
                actualPole.Year = Convert.ToInt32(ddlYear.Text);
            else
                actualPole.Year = Int32.MinValue;

            if (ddlLVisit.SelectedIndex > 0)
                actualPole.LVisit = new DateTime(Convert.ToInt32(ddlLVisit.Text), 1, 1);
            else
                actualPole.LVisit = DateTime.MinValue;

            if (ddlGuardsQuantity.SelectedIndex > 0)
                actualPole.GuardsQuantity = Convert.ToInt32(ddlGuardsQuantity.Text);
            else
                actualPole.GuardsQuantity = Int32.MinValue;

            if (ddlSection.SelectedIndex > 0)
                actualPole.Section.Id = Convert.ToInt32(((ListBoxItem)ddlSection.SelectedItem).Value);
            else
                actualPole.Section.Id = Int32.MinValue;

            actualPole.GroundWireRepair = chkGroundWireRepair.Checked;
            actualPole.Billable = chkBillable.Checked;
            actualPole.PoleTag = chkPoleTag.Checked;
            actualPole.InspBy = txtInspBy.Text.Trim();
            actualPole.Number = txtNumber.Text.Trim();
            actualPole.D804 = txtD804.Text.Trim();
            actualPole.Circuit = txtCircuit.Text.Trim();
            actualPole.InspectionResult.ServerId = Pole.InspectionResult.Id;
            actualPole.InspectionResult.Comments = txtComments.Text.Trim();
            actualPole.InspectionResult.IsElectrical = chkIsElectrical.Checked;

            actualPole.Tops.Clear();
            foreach (EXMissionStructures_PoleTopType topType in lstTopTypes.SelectedItems)
                actualPole.Tops.Add(topType);

            actualPole.Phases.Clear();
            foreach (EPhase phase in lstPhases.SelectedItems)
                actualPole.Phases.Add(phase);

            actualPole.Notes.Clear();
            foreach (ENote note in lstNotes.SelectedItems)
                actualPole.Notes.Add(note);

            actualPole.Images.Clear();
            foreach (EDistributionPoleImage image in lstImages.Items)
                actualPole.Images.Add(image);

            actualPole.Latitude = position1.GetLatitude();
            actualPole.Longitude = position1.GetLongitude();
            actualPole.Meters = grdDistributionMeters.CurrentMeters;
            
            return actualPole;
        }

        private void Save()
        {
            try
            {
                Cursor = Cursors.WaitCursor;
                EDistributionPole actualPole = GetActualPole();

                if (!Pole.isProjectPole)
                    LPole.Update(m_OutboxBase.ConnectionString, actualPole);
                else
                {
                    LPole.Update(actualPole, imagesToRemove);
                    LPole.Delete(m_OutboxBase.ConnectionString, actualPole);  
                    LPole.Save(m_OutboxBase.ConnectionString, actualPole);
                }

                Pole = actualPole;
            }
            catch (Exception ex)
            {
                RegisterError.SaveError(ex);
            }
            finally
            {
                Cursor = Cursors.Default;
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                Save();

                Close();
            }
            catch(Exception ex)
            {
                RegisterError.SaveError(ex);
            }
        }

        private void btnSearchImage_Click(object sender, EventArgs e)
        {
            SearchImage();
        }

        private void SearchImage()
        {
            try
            {
                OpenFileDialog _OpenFileDialog = new OpenFileDialog();
                DialogResult _DialogResult = _OpenFileDialog.ShowDialog();
                EDistributionPoleImage image;

                switch (_DialogResult)
                {
                    case DialogResult.OK:
                    case DialogResult.Yes:
                        FileInfo selectedFile = new FileInfo(_OpenFileDialog.FileName);

                        image = new EDistributionPoleImage();
                        image.ImageType = DistributionImageType.Pole;
                        image.FullName = selectedFile.FullName;
                        image.FileName = "Unsaved " + Path.GetFileName(selectedFile.FullName);

                        Pole.Images.Add(image);
                        LoadImages();
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                RegisterError.SaveError(ex);
            }
        }

        private void gridDistributionSectionalizers_ClickedEdit(object sender, Controls.Grid.GridBaseEventArgs e)
        {
            if (m_DistributionSectionalizerEditor == null)
                m_DistributionSectionalizerEditor = new frmDistributionSectionalizerEditor();

            m_DistributionSectionalizerEditor.Sectionalizer = gridDistributionSectionalizers.CurrentSectionalizers.Find(delegate(ESectionalizer sectionalizer) { return sectionalizer.Id == e.SelectedId; });
            m_DistributionSectionalizerEditor.Pole = Pole;
            m_DistributionSectionalizerEditor.m_OutboxBase = m_OutboxBase;

            m_DistributionSectionalizerEditor.ShowDialog();
            LoadSectionlizers();
        }

        private void gridDistributionSectionalizers_ClickedDelete(object sender, PPI.Controls.Grid.GridBaseEventArgs e)
        {
            try
            {
                if (gridDistributionSectionalizers.CurrentSectionalizers != null)
                {
                    ESectionalizer selectedSectionalizer = gridDistributionSectionalizers.CurrentSectionalizers.Find(delegate(ESectionalizer sectionalizer) { return sectionalizer.Id == e.SelectedId; });
                    string _Message = "Distribution Sectionalizer id: " + selectedSectionalizer.Id + " will be deleted from database. Are you sure you want to delete this inspection?";

                    if (MessageBox.Show(_Message, "Delete ", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
                    {
                        //Delete on local mobile database.
                        LSectionalizer.Delete(m_OutboxBase.ConnectionString, selectedSectionalizer);

                        MessageBox.Show("Deleted Succesfull");
                        gridDistributionSectionalizers.Datagrid.Rows.Remove(e.SelectedRow);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                RegisterError.SaveError(ex);
            }
        }

        private void gridDistributionReclosers_ClickedDelete(object sender, PPI.Controls.Grid.GridBaseEventArgs e)
        {
            try
            {
                if (gridDistributionReclosers.CurrentReclosers != null)
                {
                    ERecloser selectedRecloser = gridDistributionReclosers.CurrentReclosers.Find(delegate(ERecloser recloser) { return recloser.Id == e.SelectedId; });
                    string _Message = "Distribution Recloser id: " + selectedRecloser.Id + " will be deleted from database. Are you sure you want to delete this inspection?";

                    if (MessageBox.Show(_Message, "Delete ", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
                    {
                        //Delete on local mobile database.
                        LRecloser.Delete(m_OutboxBase.ConnectionString, selectedRecloser);

                        MessageBox.Show("Deleted Succesfull");
                        gridDistributionReclosers.Datagrid.Rows.Remove(e.SelectedRow);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                RegisterError.SaveError(ex);
            }
        }

        private void gridDistributionReclosers_ClickedEdit(object sender, PPI.Controls.Grid.GridBaseEventArgs e)
        {
            if (m_DistributionRecloserEditor == null)
                m_DistributionRecloserEditor = new frmDistributionRecloserEditor();

            m_DistributionRecloserEditor.Recloser = gridDistributionReclosers.CurrentReclosers.Find(delegate(ERecloser recloser) { return recloser.Id == e.SelectedId; });
            m_DistributionRecloserEditor.Pole = Pole;
            m_DistributionRecloserEditor.m_OutboxBase = m_OutboxBase;

            m_DistributionRecloserEditor.ShowDialog();
            LoadReclosers();
        }


    }
}
